صفحه اصلی >> بلاگ >> فلاتر:معماری mvvm

فلاتر:معماری mvvm

دسته:فلاتر تاریخ انتشار: 3 فوریه 2021 ایمان رضایی

 

Model – View – ViewModel (MVVM) الگوی معماری کاملاً مستقیمی است که به توسعه نرم افزار می پردازد. چه ویژگی خاصی در مورد MVVM وجود دارد؟

ما به یک معماری نیاز داریم تا بتواند در برنامه قرار گیرد که بین UI و منطق تجارت ارتباط برقرار کند. MVVM یکی از آنهاست که می تواند منطق کسب و کار را از UI تفکیک کند ، انجام این کار آسان به نظر می رسد ، اما دوست من باور کنید اگر کاری را در معماری از دست داده اید یا کار غیر دقیق انجام داده اید ، در مراحل بعدی توسعه برنامه برای مشکلات بزرگ آماده.

در اینجا قصد دارم MVVM را با یک مثال ساده توضیح دهم که به شما دانش کافی جهت اجرا در برنامه شما را می دهد.

MVVM برای انتقال منطق تجارت از View به ViewModel و Model مفید است. ViewModel واسطه بین View و Model است که همه رویدادهای کاربر را حمل می کند و نتیجه را برمی گرداند.

بنابراین ، بیایید از هر جز component جداگانه استفاده کنیم و سعی کنیم هدف آن را درک کنیم. لطفاً نمودار را هنگام مراجعه به نکات زیر مشاهده کنید ، درک درستی از جریان خواهید داشت.

Model

این مدل منبع واحدی از حقیقت است که داده های واکشی در زمان اجرا یا پرس و جوهای مربوط به پایگاه داده را حمل می کند.

این لایه می تواند شامل منطق کسب و کار ، اعتبار کد ، و غیره باشد. این لایه برای داده های محلی یا داده های زمان اجرا در پاسخ به ViewModel با ViewModel تعامل می کند.

ViewModel

ViewModel واسطه بین View و Model است ، که همه رویدادهای کاربر را می پذیرد و آنرا برای دریافت داده به Model ارسال می کند. هنگامی که مدل داده داشته باشد ، دوباره به ViewModel برمی گردد و سپس ViewModel آن اطلاعات را به View اطلاع می دهد.

ViewModel توسط چندین View قابل استفاده است ، به این معنی که یک ViewModel منفرد می تواند داده ها را به بیش از یک View ارائه دهد.

View

 

view جایی است که کاربر در حال تعامل با ابزارک هایی است که در صفحه نمایش نشان داده می شوند. این رویدادهای کاربر برخی اقدامات را که به ViewModel هدایت می شوند ، درخواست می کند و بقیه ViewModel کار را انجام می دهد. هنگامی که ViewModel داده های مورد نیاز را دارد ، View را به روز می کند.

اکنون ، ما مثالی را می خوانیم که معماری MVVM را از بین می برد ، برای اطلاع رسانی داده ها از مکانیسم Provider state استفاده خواهیم کرد.

MediaService.dart

 

import 'dart:convert';
import 'dart:io';
import 'package:meta/meta.dart';
 
import 'package:http/http.dart' as http;
import 'package:mvvm_flutter_app/model/apis/app_exception.dart';
 
class MediaService {
final String _baseUrl = "https://itunes.apple.com/search?term=";
 
Future<dynamic> get(String url) async {
dynamic responseJson;
try {
final response = await http.get(_baseUrl + url);
responseJson = returnResponse(response);
} on SocketException {
throw FetchDataException('No Internet Connection');
}
return responseJson;
}
 
@visibleForTesting
dynamic returnResponse(http.Response response) {
switch (response.statusCode) {
case 200:
dynamic responseJson = jsonDecode(response.body);
return responseJson;
case 400:
throw BadRequestException(response.body.toString());
case 401:
case 403:
throw UnauthorisedException(response.body.toString());
case 500:
default:
throw FetchDataException(
'Error occured while communication with server' +
' with status code : ${response.statusCode}');
}
}
}

MediaRepository.dart

 

import 'package:mvvm_flutter_app/model/media.dart';
import 'package:mvvm_flutter_app/model/services/media_service.dart';
 
class MediaRepository {
MediaService _mediaService = MediaService();
 
Future<List<Media>> fetchMediaList(String value) async {
dynamic response = await _mediaService.get(value);
final jsonData = response['results'] as List;
List<Media> mediaList =
jsonData.map((tagJson) => Media.fromJson(tagJson)).toList();
return mediaList;
}
}

 

MediaViewModel.dart

 

 
import 'package:flutter/cupertino.dart';
import 'package:mvvm_flutter_app/model/apis/api_response.dart';
import 'package:mvvm_flutter_app/model/media.dart';
import 'package:mvvm_flutter_app/model/media_repository.dart';
 
class MediaViewModel with ChangeNotifier {
ApiResponse _apiResponse = ApiResponse.loading('Fetching artist data');
 
Media _media;
 
ApiResponse get response {
return _apiResponse;
}
 
Media get media {
return _media;
}
 

 

/// Call the media service and gets the data of requested media data of
/// an artist.
Future<void> fetchMediaData(String value) async {
try {
List<Media> mediaList = await MediaRepository().fetchMediaList(value);
_apiResponse = ApiResponse.completed(mediaList);
} catch (e) {
_apiResponse = ApiResponse.error(e.toString());
print(e);
}
notifyListeners();
}
 
void setSelectedMedia(Media media) {
_media = media;
notifyListeners();
}
}
 

 

HomScreen.dart

 

import 'package:flutter/material.dart';
import 'package:mvvm_flutter_app/model/apis/api_response.dart';
import 'package:mvvm_flutter_app/model/media.dart';
import 'package:mvvm_flutter_app/view/widgets/player_list_widget.dart';
import 'package:mvvm_flutter_app/view/widgets/player_widget.dart';
import 'package:mvvm_flutter_app/view_model/media_view_model.dart';
 
import 'package:provider/provider.dart';
 
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
 
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
// TODO: implement initState
super.initState();
}
 
@override
Widget build(BuildContext context) {
final _inputController = TextEditingController();
ApiResponse apiResponse = Provider.of<MediaViewModel>(context).response;
List<Media> mediaList = apiResponse.data as List<Media>;
return Scaffold(
appBar: AppBar(
title: Text('Media Player'),
),
body: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: Row(
children: <Widget>[
Expanded(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 20.0),
decoration: BoxDecoration(
color: Theme.of(context).accentColor.withAlpha(50),
borderRadius: BorderRadius.circular(30.0),
),
child: TextField(
style: TextStyle(
fontSize: 15.0,
color: Colors.grey,
),
controller: _inputController,
onChanged: (value) {},
onSubmitted: (value) {
if (value.isNotEmpty) {
Provider.of<MediaViewModel>(context)
.setSelectedMedia(null);
Provider.of<MediaViewModel>(context,
listen: false)
.fetchMediaData(value);
}
},
decoration: InputDecoration(
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
prefixIcon: Icon(
Icons.search,
color: Colors.grey,
),
hintText: 'Enter Artist Name',
)),
),
),
],
),
),
mediaList != null && mediaList.length > 0
? Expanded(
child: PlayerListWidget(mediaList, (Media media) {
Provider.of<MediaViewModel>(context)
.setSelectedMedia(media);
}))
: Expanded(
child: Center(
child: Text('Search the song by Artist'),
),
),
if (Provider.of<MediaViewModel>(context).media != null)
Align(
alignment: Alignment.bottomCenter,
child: PlayerWidget(
function: () {
setState(() {});
},
)),
],
));
}
}
 

 

 

 

 
 

 


n0
n242

برای ثبت نظر باید وارد سایت شوید یا ثبت نام نمایید.


نظر شما با موفقیت در سیستم ثبت گردید.